package com.lib76.buildCode.control;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lib76.DBInfo.model.po.mysql.Database;
import com.lib76.DBInfo.model.po.mysql.DatabaseTable;
import com.lib76.DBInfo.model.po.mysql.TableColumn;
import com.lib76.DBInfo.service.DataTypeUtils;
import com.lib76.DBInfo.service.IDatabaseInfoDao;
import com.lib76.buildCode.dao.ProjectDao;
import com.lib76.buildCode.dto.AjaxResult;
import com.lib76.buildCode.dto.DatabaseInfo;
import com.lib76.buildCode.dto.DbLinkInfo;
import com.lib76.buildCode.dto.DbTableData;
import com.lib76.buildCode.dto.DtoFactory;
import com.lib76.buildCode.dto.TableResult;
import com.lib76.buildCode.dto.TreeNode;
import com.lib76.buildCode.model.DbConfig;
import com.lib76.buildCode.model.Project;
import com.lib76.buildCode.model.TableEntity;
import com.lib76.buildCode.model.TableFieldEntity;
import com.lib76.buildCode.service.DbInfoDaoManager;
import com.lib76.buildCode.service.EntityOperateServer;
import com.lib76.jsp.HttpServletUtils;

/**
 * 数据库页面控制
 * @author 张浩
 * @version 0.0.2
 */
@Controller
public class DbConfigController {
	
	@RequestMapping("/dbConfig")
	public String config(String code,Model model){
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null){
				if(project.getDbConfig() == null){project.setDbConfig(new DbConfig());}
				model.addAttribute("project",project);
				model.addAttribute("dbConfig",project.getDbConfig());
				return "dbConfig/edit";
			}
		}
		return HttpServletUtils.sendRedirect("/","index");
	}
	
	@RequestMapping("/dbConfig/tree")
	@ResponseBody
	public List<TreeNode> tree(String code,String pid){
		List<TreeNode> result = new ArrayList<TreeNode>();
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null && project.getDbConfig() != null){
				if("news".equals(pid)){
					Collection<TableEntity> data = project.getDbConfig().getTables().values();
					for(TableEntity table:data){
						if(!table.getIsExist()){
							TreeNode node = new TreeNode();
							node.setPid("news");
							node.setId(table.getTableName());
							node.setName(table.getTableChinaName());
							node.setIsLeaf(true);
							result.add(node);
						}
					}
				}else if("exist".equals(pid)){
					Collection<TableEntity> data = project.getDbConfig().getTables().values();
					for(TableEntity table:data){
						if(table.getIsExist()){
							TreeNode node = new TreeNode();
							node.setPid("exist");
							node.setId(table.getTableName());
							node.setName(table.getTableChinaName());
							node.setIsLeaf(true);
							result.add(node);
						}
					}
				}
			}
			if(StringUtils.isBlank(pid)){
				TreeNode node = new TreeNode();
				node.setId("news");
				node.setName("新创建");
				node.setIsLeaf(false);
				result.add(node);
				node = new TreeNode();
				node.setId("exist");
				node.setName("已存在");
				node.setIsLeaf(false);
				result.add(node);
			}
		}
		return result;
	}
	
	@RequestMapping("/dbConfig/table/edit")
	public String tableEdit(String code,String tableName,Model model){
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null && project.getDbConfig() != null){
				TableEntity table = null;
				if(StringUtils.isNotBlank(tableName)){
					table = project.getDbConfig().getTables().get(tableName);
				}
				if(table == null){table = new TableEntity();}
				model.addAttribute("project", project);
				model.addAttribute("table",table);
				return "dbConfig/editTable";
			}
		}
		return HttpServletUtils.sendRedirect("/","index");
		
	}
	
	@RequestMapping("/dbConfig/table/field")
	@ResponseBody
	public TableResult<TableFieldEntity> tableField(String code,String tableName){
		TableResult<TableFieldEntity> result = new TableResult<TableFieldEntity>();
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null && project.getDbConfig() != null){
				TableEntity tableEntity = project.getDbConfig().getTables().get(tableName);
				if(tableEntity != null){
					result.setData(new ArrayList<TableFieldEntity>(tableEntity.getFields().values()));
				}
			}
		}
		return result;
	}
	
	@RequestMapping("/dbConfig/table/field/edit")
	public String tableFieldEdit(String code,String tableName,String fieldName,Model model){
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null && project.getDbConfig() != null){
				TableEntity tableEntity = project.getDbConfig().getTables().get(tableName);
				if(tableEntity != null){
					if(StringUtils.isNotBlank(fieldName)){
						TableFieldEntity field = tableEntity.getFields().get(fieldName);
						if(field != null){
							model.addAttribute("field", field);
						}else{model.addAttribute("field", new TableFieldEntity());}
					}else{
						model.addAttribute("field", new TableFieldEntity());
					}
					model.addAttribute("table", tableEntity);
				}else{
					model.addAttribute("field", new TableFieldEntity());
				}
				model.addAttribute("project", project);
			}
		}
		return "dbConfig/editField";
	}
	
	@RequestMapping("/dbConfig/table/save")
	@ResponseBody
	public AjaxResult tableSave(TableEntity table,String id,String code){
		AjaxResult result = new AjaxResult(0);
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null && project.getDbConfig() != null){
				table.setIsExist(false);
				if(StringUtils.isBlank(table.getTableChinaName())){
					table.setTableChinaName(table.getTableName());
				}
				if(StringUtils.isNotBlank(id)){
					TableEntity temp = project.getDbConfig().getTables().remove(id);
					if(temp != null){
						table.setFields(temp.getFields());
						table.setIsExist(temp.getIsExist());
					}
				}
				EntityOperateServer.updateTableEntity(project, table); //修改并保存
				result.setData(table);
				result.setError(1);
			}else{result.setMsg("无法找到的项目或项目不支持数据库");}
		}else{result.setMsg("无效的参数");}
		return result;
	}
	
	@RequestMapping("/dbConfig/table/field/save")
	@ResponseBody
	public AjaxResult tableFieldSave(TableFieldEntity field,String id,String projectCode,String tableName){
		AjaxResult result = new AjaxResult(0);
		if(StringUtils.isNotBlank(projectCode)){
			Project project = ProjectDao.findByCode(projectCode);
			if(project != null && project.getDbConfig() != null){
				if(StringUtils.isNotBlank(tableName)){
					TableEntity tableEntity = project.getDbConfig().getTables().get(tableName);
					if(tableEntity != null){
						EntityOperateServer.saveTableFieldEntity(project,tableEntity,id,field);
						result.setError(1);
					}else{result.setMsg("找不到数据库表："+tableName);}
				}else{result.setMsg("无效的表名称参数");}
			}else{result.setMsg("无法找到的项目或项目不支持数据库");}
		}else{result.setMsg("无效的项目代码参数");}
		return result;
	}
	
	@RequestMapping("/dbConfig/table/field/del")
	@ResponseBody
	public AjaxResult tableFieldDelete(String code,String tableName,String fieldName){
		AjaxResult result = new AjaxResult(0);
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null && project.getDbConfig() != null){
				if(StringUtils.isNotBlank(tableName)){
					TableEntity tableEntity = project.getDbConfig().getTables().get(tableName);
					if(tableEntity != null){
						EntityOperateServer.deleteTableFieldEntity(project,tableEntity,fieldName);
						result.setError(1);
					}else{result.setMsg("找不到数据库表："+tableName);}
				}else{result.setMsg("无效的表名称参数");}
			}else{result.setMsg("无法找到的项目或项目不支持数据库");}
		}else{result.setMsg("无效的项目代码参数");}
		return result;
	}

	@RequestMapping("/dbConfig/table/select")
	public String tableSelect(String code,Model model){
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null){
				if(project.getDbConfig() == null){project.setDbConfig(new DbConfig());}
				model.addAttribute("project",project);
				return "dbConfig/select";
			}
		}
		return HttpServletUtils.sendRedirect("/","index");
	}
	
	/**
	 * 保存已有的数据库表配置
	 * @param databaseName
	 * @param tableNames
	 * @param code
	 * @param key
	 * @param model
	 * @return
	 */
	@RequestMapping("/dbConfig/table/select/save")
	public String selectSave(String databaseName,String tableNames,String code,String key,Model model){
		if(StringUtils.isNotBlank(code) && StringUtils.isNotBlank(key)){
			Project project = ProjectDao.findByCode(code);
			IDatabaseInfoDao dbInfoDao = DbInfoDaoManager.getDbInfoDao(key);
			if(project != null && dbInfoDao != null){
				DbConfig config = project.getDbConfig();
				if(config != null && StringUtils.isNotBlank(tableNames)){
					String[] arrTable = tableNames.split(",");
					List<DatabaseTable> data = dbInfoDao.findAllTable(databaseName);
					for(DatabaseTable table : data){
						if(ArrayUtils.contains(arrTable, table.getTableName())){
							TableEntity entity = new TableEntity();
							entity.setIsExist(true);
							entity.setTableName(table.getTableName());
							if(StringUtils.isNotBlank(table.getComment())){
								entity.setTableChinaName(table.getComment());
							}else{
								entity.setTableChinaName(table.getTableName());
							}
							//查询表字段
							List<TableColumn> columns = dbInfoDao.findAllColumn(databaseName, table.getTableName());
							for(TableColumn column : columns){
								TableFieldEntity tableFieldEntity = new TableFieldEntity();
								tableFieldEntity.setCode(column.getColumnName());
								if(StringUtils.isNotBlank(column.getComment())){
									tableFieldEntity.setName(column.getComment());
								}else{
									tableFieldEntity.setName(column.getColumnName());
								}
								tableFieldEntity.setType(DataTypeUtils.mySqlDbType2JavaType(column.getDataType()));
								tableFieldEntity.setLength(column.getCharMaxLength());
								tableFieldEntity.setIsNullable(column.getIsNullable());
								if(StringUtils.isNotBlank(column.getColumnKey())){
									tableFieldEntity.setIsKey(true);
								}
								entity.getFields().put(tableFieldEntity.getCode(),tableFieldEntity);
							}
							EntityOperateServer.addTableEntity(project, entity); //保存数据库表
						}
					}
				}
				return HttpServletUtils.sendRedirect("/dbConfig?code="+code);
			}
		}
		return HttpServletUtils.sendRedirect("/","index");
	}
	
	@RequestMapping("/dbConfig/save")
	@ResponseBody
	public AjaxResult save(DbLinkInfo linkInfo,String code,String databaseName,String[] spaces,String tablePattern,Model model){
		AjaxResult result = new AjaxResult(0);
		if(StringUtils.isNotBlank(code)){
			Project project = ProjectDao.findByCode(code);
			if(project != null){
				DbConfig config = project.getDbConfig();
				if(config != null){
					EntityOperateServer.updateEntityClassName(project, spaces, tablePattern); //更新实体类名
					config.setIp(linkInfo.getIp());
					config.setPort(linkInfo.getPort());
					config.setUserName(linkInfo.getUserName());
					config.setUserPwd(linkInfo.getUserPwd());
					config.setDatabaseName(databaseName);
					config.setSpaces(spaces);
					config.setTablePattern(tablePattern);
					result.setError(1);
				}else{
					result.setMsg("项目不支持数据库");
				}
			}else{
				result.setMsg("无法找到的项目");
			}
		}else{
			result.setMsg("无效的项目代码参数");
		}
		return result;
	}
	
	@RequestMapping("/dbConfig/linkDatabase")
	@ResponseBody
	public DatabaseInfo linkDatabase(DbLinkInfo linkInfo){
		if(StringUtils.isNotBlank(linkInfo.getIp()) && StringUtils.isNotBlank(linkInfo.getUserName())){
			IDatabaseInfoDao dbInfoDao = DbInfoDaoManager.createDbInfoDao(linkInfo);
			String key = DbInfoDaoManager.buildKey(linkInfo);
			//组装前台数据
			DatabaseInfo info = new DatabaseInfo();
			info.setItem(new TreeNode());
			info.getItem().setId(key);
			info.getItem().setName(key);
			//获取所有数据库
			List<Database> data = dbInfoDao.findAllDatabase();
			if(data != null && data.size() >0){
				info.setTables(new ArrayList<TreeNode>());
				for(Database database : data){
					TreeNode child = new TreeNode();
					child.setId(info.getItem().getId() + database.getSchemaName().hashCode());
					child.setName(database.getSchemaName());
					child.setPid(info.getItem().getId());
					child.setIsLeaf(true);
					info.getTables().add(child);
				}
			}
			return info;
			
		}
		return null;
	}
	
	/**
	 * 查找数据库所有表信息
	 * @param key
	 * @param tableSchema
	 * @return
	 */
	@RequestMapping("/dbConfig/searchTables")
	@ResponseBody
	public List<DbTableData> searchTables(String key,String tableSchema){
		List<DbTableData> result = new ArrayList<DbTableData>();
		IDatabaseInfoDao dbInfoDao = DbInfoDaoManager.getDbInfoDao(key);
		if(dbInfoDao != null){
			List<DatabaseTable> data = dbInfoDao.findAllTable(tableSchema);
			for(DatabaseTable table : data){
				result.add(DtoFactory.changeDbTableData(table));
			}
		}
		return result;
	}
	
	@RequestMapping("/dbConfig/searchColumns")
	@ResponseBody
	public List<TableColumn> searchTableColumns(String key,String tableSchema,String tableName){
		IDatabaseInfoDao dbInfoDao = DbInfoDaoManager.getDbInfoDao(key);
		if(dbInfoDao != null){
			List<TableColumn> data = dbInfoDao.findAllColumn(tableSchema, tableName);
			return data;
		}
		return null;
	}
}
